<?php
/**
 * Управления динамическими страницами.
 * @author nrnwest@gmail.com
 *
 */
class Arm_Page
{
    /**
     * Поля страници которые записываються в шаблоны страниц, когда они записываются в директорию модуля.
     * @var array
     */
    private $_fieldTemplate = array('uri', 'lang', 'title', 'description', 'keywords', 'body');
    
    /**
     * Ключ который передается в контролер если страница существует с данными страници.
     * 
     */
    const PARAMS_KEY_DATA = 'arm_page_data';
     /**
      * Поле uri
      */
     const URI = 'uri';
    
     /**
      * Индефикатор пользователя
      */
     const ID_USER = 'id_user';
     
     /**
      * Время создания 
      */
     const TIME_CREATE = 'time_create';
     
     /**
      * Заголовок страници
      */
     const TITLE = 'title';
     
     /**
      * индефикатор модуля
      */
     const ID_MODULE = 'id_module';
     

     
    /**
     * Arm_Page_Sql_Pdo_Mysql
     * @var Arm_Page_Sql_Pdo_Mysql
     */
    private $_sql;
    
    /**
     * Arm_Filter_Url
     * 
     * @var Arm_Filter_Url
     */
    private $_urlFilter = null;
    
    
    public function __construct()
    {
      $this->_sql = Arm_Db::getSqlObject('Arm_Page_Sql');
      $this->_urlFilter = new Arm_Filter_Url();
    }
    
    /**
     * Создания страници
     * @param array $data
     * @return int id созданой страници
     */
    public function create(array $data, $lang=null)
    {
      if(array_key_exists(self::URI, $data) === false) {
          throw new Arm_Page_Exception(Arm_Translate::_('Вы не передали обязательный ключ %s', self::URI));
      } 
      if(array_key_exists(self::ID_MODULE, $data) === false) {
          throw new Arm_Page_Exception(Arm_Translate::_('Вы не передали обязательный ключ %s', self::ID_MODULE));
      }
      $data[self::URI] = $this->_urlFilter->filter($data[self::URI]);
      if(array_key_exists(self::ID_USER, $data) === false) {
          $data[self::ID_USER] = Arm_User::getInstance()->getId();
      }
      $data[self::TIME_CREATE] = time();
      
      $idPage =  (int)$this->_sql->create($data, $lang);
      
      return $idPage;
    }
    
    

    
    /**
     * Проверка на наличия страници
     * @param string $uri
     * @return bool
     */
    public function isPage($uri)
    {
       $uri = $this->_urlFilter->filter($uri);
       if(false === $this->_sql->getIdPageUrl($uri)) {
           return false;
       }
       return true;
    }
    
    /**
     * Вернет id страници
     * @param string $uri урл страници
     */
    public function getIdPage($uri)
    {
      $uri = $this->_urlFilter->filter($uri);
      return $this->_sql->getIdPageUrl($uri);
    }
    
    
    /**
     * Получения страницы
     * @param string $uri
     * @param int  $id
     * @param bool $getSrc если установить в true преобразования тела не будет происходить.
     * @return array|false
     */
    public function getPage($uri = null, $id = null, $getSrc = false)
    {
       if($uri === null and $id === null) {
           throw new Arm_Page_Exception(Arm_Translate::_('Вы должны указать $uri или $id'));
       }
       
       $uri = $this->_urlFilter->filter($uri);
       
       if($id === null) {
           $id = $this->_sql->getIdPageUrl($uri);
       }

       if($id === false) {
           return false;
       }
       $result = $this->_sql->getPage($id);
       
      if($result === false) {
          return false;
      }
      if($getSrc) {
          return $result;
      }
       // выполним код php в body подключим помощников вида и фильтров, которые доступны 
       // в приложении, и с учетом принадлежности старницы к модулю.
       // если страница проектная то подключаем помощники модуля default
      
       if($result[self::ID_MODULE] === '0') {
           $module = 'default';
       } else {
           $module = Arm_Module::getInstance()->getNameModule($result[self::ID_MODULE]);
       }  
        $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
        if($viewRenderer->view === null) {
            $viewRenderer->view = new Arm_View();
        }
        $this->_setViewParams($viewRenderer->view, $module);
        $result['body'] = $viewRenderer->view->renderEval($result['body'], 'Page id:' . $result['id'] . ' Page - uri:' . $result['uri']);
       return $result;
    }
    
    /**
     * Устновка путей для обьекта view перед выполнениям
     * body страницы.
     * @param Zend_View $view
     * @param string $module
     */
    protected function _setViewParams($view, $module)
    {
       // устновка пощников и фильтров Zend
        $view->setHelperPath('Zend/View/Helper/', 'Zend_View_Helper_');
        $view->setFilterPath('Zend/View/Filter/', 'Zend_View_Filter_');
        // Arm
        $pathLibrary = Arm_Core::getPathLibrary();
        $view->addFilterPath($pathLibrary . 'Arm/View/Filter/', 'Arm_View_Filter_');
        $view->addHelperPath($pathLibrary . 'Arm/View/Helper/', 'Arm_View_Helper_');
        // Модуля
        $pathModule = Arm_Core::getPathModule($module);
        $view->addFilterPath($pathModule . 'filters/', ucfirst($module) . '_View_Filter_');
        $view->addHelperPath($pathModule . 'helpers/', ucfirst($module) . '_View_Helper_');
    }
    
    /**
     * Обновления страниц, обновляются только старинци в базе данных.
     * @param array $data
     * @param int|null $idPage индефикатор страници если null должен быть указан $uri
     * @param string|null $uri урл страници
     * @return int вернет id станици 
     */
    public function upDate($data, $idPage = null, $uri = null)
    {
     if($uri === null and $idPage === null) {
           throw new Arm_Page_Exception(Arm_Translate::_('Вы должны указать $uri или $idPage'));
       }
        if($idPage === null) {
       $uri = $this->_urlFilter->filter($uri);
       $idPage = $this->getIdPage($uri);
       }
       $this->_sql->updatePage($idPage, $data);
       return $idPage;
    }
    
    
    /**
     * Удаления страници по ее $idPage или по $uri
     * @param int $idPage
     * @param string $uri
     */
    public function deletePage($idPage = null, $uri = null)
    {
         if($uri === null and $idPage === null) {
           throw new Arm_Page_Exception(Arm_Translate::_('Вы должны указать $uri или $idPage'));
       }
       if($idPage === null) {
       $uri = $this->_urlFilter->filter($uri);
       $idPage = $this->getIdPage($uri);
       }
       $this->_sql->deletePage($idPage);
       return;
    }
    
    /**
     * Удаления страниц модуля.
     * @param int $idModule
     */
    public function deletePagesModule($idModule)
    {
        $this->_sql->deletePageModule($idModule);
        return;
    }
    
    /**
     * Получения всех страниц или страниц определеного модуля.
     * 
     * 
     * @param int|null $idModule если null все страницы в системе
     * @param string|null $lang если null язык установиться текущий.
     * @return array
     */
    public function getPages($idModule=null, $lang=null)
    {
        return $this->_sql->getPages($idModule, $lang);   
    }
    

    
    /**
     * Созадния страниц модуля в директории module/install/pages/
     * Эта опреция удалит все существующие страницы в данной директории.
     * Страницы создаются для всех зарегистрованных языоков.
     * 
     * @param int $idModule
     */
    public function createPageInstallModule($idModule, $lang=null)
    { 
      // получаем для всех языок страницы модуля
      $pages = array();
       foreach (Arm_Translate::getInstance()->getLanguages() as $k=>$v) {  
         $pag = $this->getPages($idModule, $k);
         if($pag === array()) {
             continue;
         }
         $pages = array_merge($pages, $pag);
      }
      
     if($pages === array()) {
         return;
     }
     $path = Arm_Core::getPathModule(Arm_Module::getInstance()->getNameModule($idModule)) . 'install/pages/';
     $delFile = glob($path . "*.phtml");
     foreach ($delFile as $file) {
         unlink($file);
     } 
     
     $template = file_get_contents(dirname(__FILE__) . '/Page/template.phtml');
     $langs = array();
     foreach (Arm_Translate::getInstance()->getLanguages() as $k=>$v) {
         $langs[$v['id']] = $k;
     }
     
     foreach ($pages as $p) {
         $searsh = array();
         $replace = array();
         $p['lang'] = $langs[$p['id_lang']];
         $nameFile = $p['lang'] . '_' . str_replace('/', '_', trim($p[self::URI], '/\\')) . '.phtml';
         $fp = fopen($path . $nameFile, 'wb');
         
         foreach ($this->_fieldTemplate as $field) {
             $searsh[] = '{' . $field . '}';
             if($field !== 'body') {
                $replace[] = addcslashes($p[$field], "'\\");
             } else {
                 $replace[] = $p[$field];
             }
         }
         $str = str_replace($searsh, $replace, $template);
         fwrite($fp, $str);
         fclose($fp);    
     }
      return;
    }
    
    
    
    /**
     * запись модульных страниц c module/install/pages/ в общею таблицу страниц.
     * Данный метод удалит все страницы модуля с общей таблицы страниц.
     * @param string $module
     * @param int|null $idUser id текущего пользователя
     * @return int сколько страниц записано.
     */
    public function writePagesInstallModule($module, $idUser=null)
    {
       if($idUser === null) { 
          $idUser = Arm_User::getInstance()->getId(); 
       }
       
       $idModule = Arm_Module::getInstance()->getIdModule($module);
       $this->deletePagesModule($idModule);
      $langs = array();
     foreach (Arm_Translate::getInstance()->getLanguages() as $k=>$v) {
         $langs[$k] = $v['id'];
     }
       // читаем файлы, и записываем их в базу.
        $path = Arm_Core::getPathModule($module) . 'install/pages/';
        $file = glob($path . "*.phtml");
        $count = 0;
        foreach ($file as $f) {
          $params = $this->_helperGetParams($f);
          // получим язык и проверим существует ли он
          if(array_key_exists($params['lang'], $langs) === false) {
              // в системе не существует языка, для которой есть
              // перевод страници.
              continue;
          }
          // запишем id модуля
          $params['id_module'] = $idModule;
          // получим тело страницы
          $params['body'] = $this->_helperGetBody($f);
          // нужно записать id пользователя.
          $params['id_user'] = $idUser;
          // запишем страницу 
          $this->create($params, $params['lang']); 
          $count++;
        } 
        return $count; 
    }
    
    /**
     * Получаем переменую $params
     * @param path $file путь к файлу страницы
     */
    protected function _helperGetParams($file)
    {
     return require $file;
    }
    
    /**
     * Вернет толо страницы, беза масива $params
     * @param path $file
     * @return string
     */
    protected function _helperGetBody($file)
    {
      $str = file_get_contents($file);
      $str = preg_replace('~\<\?php.*\?\>~iusU', '', $str, 1);
      return trim($str);
    }
    
    
    /**
     * Удаления страниц  которые не имеют свзяи с таблицой навигации.
     * Таблицы удаляться с системной таблицы страниц.
     * 
     * @return void
     */
    public function deletePageNotNavigation()
    {
     return $this->_sql->deletePageNotNavigation();
    }

    
    
    

}